﻿Imports System.IO

''' <summary>
''' Represents a CSV-based database.
''' </summary>
Public Class CsvDatabase

    Private _location As String = String.Empty

    Private _tables As New Dictionary(Of String, CsvTable)

    ''' <summary>
    ''' Provides access to each of the tables that are contained in the database.
    ''' </summary>
    ''' <value>The tables that make up the database.</value>
    Public Property Tables(ByVal tableName As String) As CsvTable
        Get
            Return _tables(tableName)
        End Get
        Set(ByVal value As CsvTable)
            If Not _tables.ContainsKey(tableName) Then Throw New Exception("The table '" + tableName + "' does not exist.")
            _tables(tableName) = value
        End Set
    End Property

    ''' <summary>
    ''' Initializes a new instance of the <see cref="CsvDatabase" /> class.
    ''' </summary>
    ''' <param name="location">The location of the database files.</param>
    ''' <param name="schema">The schema of the database to load the database against.</param>
    Private Sub New(ByVal location As String, ByVal schema As DatabaseSchema)

        ' Set the location
        Me._location = location

        ' Load the tables
        For Each Table As TableSchema In schema.AllTables

            ' Create the table if it does not already exist
            Dim FileName As String = Path.Combine(_location, Table.Name + ".csv")
            If Not IO.File.Exists(FileName) Then CsvTable.Create(FileName, Table)

            ' Load the table
            Dim File As CsvTable = CsvTable.Load(FileName, Table)
            _tables.Add(Table.Name, File)

        Next

    End Sub

    ''' <summary>
    ''' Connects to a physical CSV-based database whose schema conforms to the schema passed in. The database
    ''' will be modified to conform to the schema if necessary, and it is possible to create the database if
    ''' it does not already exist.
    ''' </summary>
    ''' <param name="location">The location of the database files.</param>
    ''' <param name="schema">The schema of the database to load the database against.</param>
    ''' <param name="createDatabaseIfNecessary">If set to <c>true</c>, the database will be created if it does not already exist.</param>
    ''' <returns>An interface to work with the database.</returns>
    Public Shared Function Connect(ByVal location As String, _
                                   ByVal schema As DatabaseSchema, _
                                   ByVal createDatabaseIfNecessary As Boolean) As CsvDatabase

        ' Create the database if necessary
        If Not Directory.Exists(location) AndAlso createDatabaseIfNecessary Then
            CreateDatabase(location, schema)
        End If

        ' Does the database exist?
        If Not Directory.Exists(location) Then
            Throw New Exception("There is no database at the location '" + location + "'.")
        End If

        ' Open the database
        Return New CsvDatabase(location, schema)

    End Function

    Private Shared Sub CreateDatabase(ByVal location As String, ByVal schema As DatabaseSchema)

        ' Create the database based on the given schema
        If Directory.Exists(location) Then Throw New Exception("The location '" + location + "' already exists.")
        Directory.CreateDirectory(location)

        ' Process each table
        For Each Table As TableSchema In schema.AllTables
            Dim TableFileName As String = Path.Combine(location, Table.Name + ".csv")
            CsvTable.Create(TableFileName, Table)
        Next

    End Sub

End Class
